package com.yupi.maker.meta;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.yupi.maker.meta.Meta.ModelConfig;
import com.yupi.maker.meta.Meta.FileConfig;
import com.yupi.maker.meta.enums.FileGenerateTypeEnum;
import com.yupi.maker.meta.enums.FileTypeEnum;
import com.yupi.maker.meta.enums.ModelTypeEnum;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @version 1.0
 * @Author moresuo
 * @Date 2024/9/11 22:00
 * @注释
 */
public class MetaValidator {
    public static void doValidAndFill(Meta meta){
        //校验根信息
        validAndFillMetaRoot(meta);
        //校验文件配置信息
        validAndFillFileConfig(meta);
        //校验数据模型信息
        validAndFillModelConfig(meta);

    }

    /**
     * 校验数据模型参数
     * @param meta
     */
    private static void validAndFillModelConfig(Meta meta) {
        //modelConfig校验和默认值
        ModelConfig modelConfig = meta.getModelConfig();
        if (modelConfig == null) {
            return;
        }
        List<ModelConfig.ModelInfo> models = modelConfig.getModels();
        if (CollectionUtil.isEmpty(models)) {
            return;
        }
        for (ModelConfig.ModelInfo model:models) {
            //为group不校验
            String groupKey = model.getGroupKey();
            if(StrUtil.isNotBlank(groupKey)){
                //生成中间参数，也就是命令参数，例如--help
                String allArgsStr = model.getModels().stream().map(subModelInfo -> {
                    return String.format("\"--%s\"", subModelInfo.getFieldName());
                }).collect(Collectors.joining(", "));
                model.setAllArgsStr(allArgsStr);
                continue;
            }
            String fieldName = model.getFieldName();
            if (StrUtil.isBlank(fieldName)) {
                throw new MetaException("未填写 fieldName");
            }
            //默认为String类型
            String modelInfoType = StrUtil.blankToDefault(model.getType(), ModelTypeEnum.STRING.getValue());
            model.setType(modelInfoType);
        }
    }

    /**
     * 校验文件的配置信息
     * @param meta
     */
    private static void validAndFillFileConfig(Meta meta) {
        //fileConfig校验和默认值
        FileConfig fileConfig = meta.getFileConfig();
        if (fileConfig == null) {
            return;
        }
        //sourceRootPath必填，文件的原始路径
        String sourceRootPath= fileConfig.getSourceRootPath();
        if(StrUtil.isBlank(sourceRootPath)){
            throw new MetaException("未填写sourceRootPath");
        }

        //原始文件输入路径
        String defaultInputRootPath = ".source/" + FileUtil.getLastPathEle(Paths.get(sourceRootPath));
        String inputRootPath= StrUtil.blankToDefault(fileConfig.getInputRootPath(),defaultInputRootPath);
        fileConfig.setInputRootPath(inputRootPath);

        //代码生成后的源文件路径
        String defaultOutputRootPath = "generated";
        String outputRootPath= StrUtil.blankToDefault(fileConfig.getOutputRootPath(),defaultOutputRootPath);
        fileConfig.setOutputRootPath(outputRootPath);

        //输出文件的类型
        String defaultFileConfigType = FileTypeEnum.DIR.getValue();
        String fileConfigType=StrUtil.blankToDefault(fileConfig.getType(),defaultFileConfigType);
        fileConfig.setType(fileConfigType);

        List<FileConfig.FileInfo> files = fileConfig.getFiles();
        if (!CollectionUtil.isNotEmpty(files)) {
            return;
        }
        for (FileConfig.FileInfo fileInfo: files) {
            String type=fileInfo.getType();
            //如果是文件组
            if (Objects.equals(type, FileTypeEnum.GROUP.getValue())) {
                continue;
            }

            //inputPath
            String inputPath=fileInfo.getInputPath();
            if (StrUtil.isBlank(inputPath)) {
                throw new MetaException("inputPath未填写");
            }
            //输出路径默认为输入路径
            String outputPath = StrUtil.blankToDefault(fileInfo.getOutputPath(),inputPath);
            fileInfo.setOutputPath(outputPath);

            //inputPath有文件后缀为file,没有则为dir
            if(StrUtil.isBlank(type)){
                //无文件后缀
                if (StrUtil.isBlank(FileUtil.getSuffix(inputPath))) {
                    fileInfo.setType(FileTypeEnum.DIR.getValue());
                }else{
                    fileInfo.setType(FileTypeEnum.FILE.getValue());
                }
            }
            String generateType=fileInfo.getGenerateType();
            if (StrUtil.isBlank(generateType)) {
                //如果输入路径后缀以.ftl结尾说明是模板文件，为动态文件
                if (inputPath.endsWith(".ftl")) {
                    fileInfo.setGenerateType(FileGenerateTypeEnum.DYNAMIC.getValue());
                }else{
                    fileInfo.setGenerateType(FileGenerateTypeEnum.STATIC.getValue());
                }
            }
        }
    }

    /**
     * 校验根信息
     * @param meta
     */
    private static void validAndFillMetaRoot(Meta meta) {
        // 校验并填充默认值
        String name = StrUtil.blankToDefault(meta.getName(), "my-generator");
        String description = StrUtil.emptyToDefault(meta.getDescription(), "我的模板代码生成器");
        String author = StrUtil.emptyToDefault(meta.getAuthor(), "yupi");
        String basePackage = StrUtil.blankToDefault(meta.getBasePackage(), "com.yupi");
        String version = StrUtil.emptyToDefault(meta.getVersion(), "1.0");
        String createTime = StrUtil.emptyToDefault(meta.getCreateTime(), DateUtil.now());
        meta.setName(name);
        meta.setDescription(description);
        meta.setAuthor(author);
        meta.setBasePackage(basePackage);
        meta.setVersion(version);
        meta.setCreateTime(createTime);
    }
}
